#include <stdx/all.h>


class EncodeApplication : public Application
{
protected:
	int sz;
	string filepath;
	SmartBuffer buffer;

	void printTips() const
	{
		puts("  cppcode parameter");
		puts("--------------------------------------------------");
		puts("  -i : interactive model");
		puts("  -s : source filename [required]");
		puts("  -o : output filename [required]");
		puts("--------------------------------------------------");
		puts("");
	}
	bool checkCommand(string& msg)
	{
		File file;
		const char* cmd = GetCmdParam("-s");

		if (cmd == NULL || *cmd == 0)
		{
			msg = "please input source filename [-s filename]";
			
			return false;
		}
		
		cmd = GetCmdParam("-o");

		if (cmd == NULL || *cmd == 0)
		{
			msg = "please input output filename [-o filename]";

			return false;
		}

		if (GetCmdParam("-i") && path::size(cmd) > 0)
		{
			CHECK_FALSE_RETURN(cmdx::CheckCommand("file[%s] exists, overwrite or not ? (y/n)", path::name(cmd).c_str()));
		}

		filepath = cmd;

		this->sz = stdx::GetFileContent(buffer, GetCmdParam("-s"));
		
		if (this->sz <= 0)
		{
			msg = "system io error";

			return false;
		}

		return true;
	}
	int getExportSource(string& src)
	{
		const u_char* str = buffer.ptr();
		const u_char* end = buffer.ptr() + sz;

		while (str < end)
		{
			src += "\n\t\t";

			for (int i = 0; i < 16 && str < end; i++, str++)
			{
				if (str + 1 == end)
				{
					stdx::append(src, "0x%02X", *str);
				}
				else
				{
					stdx::append(src, "0x%02X,", *str);
				}
			}
		}

		return src.length();
	}
	bool exportSourceFile()
	{
		TextFile out;

		string name = path::name(filepath);

		stdx::toupper(name);

		name = stdx::replace(name, " ", "_");
		name = stdx::replace(name, ".", "_");
		name = stdx::replace(name, "+", "_");
		name = stdx::replace(name, "-", "_");

		CHECK_FALSE_RETURN(out.open(filepath, true));

		out << "#ifndef XG_" << name << "\n";
		out << "#define XG_" << name << "\n";
		out.puts("/////////////////////////////////////////////////////////////////////");

		out.tr();
		out.puts("#include <stdx/std.h>");

		out.tr().tr().tr();

		out.puts("static SmartBuffer GetSourceData()");
		out.puts("{");

		string src = "\tstatic u_char data[] = {";

		getExportSource(src);

		src += "\n\t};";

		out.puts(src.c_str());
		out.tr();
		out.puts("\tSmartBuffer buffer(sizeof(data));");
		out.tr();
		out.puts("\tmemcpy(buffer.str(), data, sizeof(data));");
		out.tr();
		out.puts("\treturn buffer;");
		out.puts("}");
		out.tr().tr();

		out.puts("#endif");

		return true;
	}
public:
	bool main()
	{
		string msg;

		if (GetCmdParamCount() <= 1 || GetCmdParam("?") || GetCmdParam("--help"))
		{
			printTips();

			return true;
		}

		if (checkCommand(msg))
		{
			if (exportSourceFile())
			{
				SetConsoleTextColor(eGREEN);
				puts("export c++ source success");
				SetConsoleTextColor(eWHITE);
			}
			else
			{
				msg = "export c++ source failed";

				goto __ERROR__;
			}
		}
		else
		{
			goto __ERROR__;
		}

		return true;

	__ERROR__:

		if (msg.empty()) return false;

		SetConsoleTextColor(eRED);
		puts(msg.c_str());
		SetConsoleTextColor(eWHITE);

		return false;
	}
};

START_APP(EncodeApplication)